package com.cbw.utils;
import com.cbw.bean.Express;
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;

/**C/S通信工具类
 * 信息处理工具类:(只负责Client与Server间的信息处理)
 *    1.规定的命令(即规定数据增删改查)
 *    2.提取客户端与服务器收发信息的方法(即提取IO流操作)
 *
 * 客户端服务端都是靠Socket对象进行通信的，都要使用socket中的网络进行传输数据，
 * 所以C/S通信封装的方法参数都少不了socket对象(借助流)对数据的发送和接收。
 */
public class MsgUtil {
    //定义公开的常量命令(增删改查命令)，通过命令，让服务器执行对应的方法
    //服务器需要做的事情
    public static final String CMD_ADD="ADD"; //添加命令
    public static final String CMD_REMOVE="REMOVE"; //删除命令
    public static final String CMD_MODIFY="MODIFY";//修改命令
    public static final String CMD_QUERY="QUERY";//查询命令
    public static final String CMD_SIZE="SIZE"; //查询快递柜中快递量
    public static final String CMD_PICK="PICK"; //取快递
    public static final String CMD_CHECKE_FULL = "FULL";//快递柜判空
    public static final String CMD_FIND_BY_NUMBER  ="FIND_BY_NUMBER";//通过单号判断快递存在否


    /**
     * 1.输出快递对象，客户端和服务器端都会用到
     * 客户端发送express,服务器端接收
     * 服务器端发送express，客户端接收
     * @param socket
     * @param express
     */
    public static void sendExpress(Socket socket, Express express) throws IOException {
        //将socket中网络输出流转换成(装饰)序列化输出流
        //序列化流不仅可以文件上的对象传输，还可以网络上的对象传输，下面就是网络中传输对象
        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        oos.writeObject(express);//输出对象
    }

    /**
     * 2.接收快递对象,客户端和服务器都会用到
     * @param socket
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static Express receiveExpress(Socket socket) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
        return (Express) ois.readObject();//读取对象并返回
    }

    /**
     * 发送命令--命令是String类型
     * @param socket
     * @param cmd
     */
    public static void sendStr(Socket socket,String cmd) throws IOException {
        //推荐使用数据流(只要传的不是对象)，序列化流有坑，先将socket网络流转成数据流
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.writeUTF(cmd);//输出字符串
    }

    /**
     * 接收命令--命令是String类型
     * @param socket
     * @return
     * @throws IOException
     */
    public static String receiveCmd(Socket socket) throws IOException {
        //将socket网络流转成数据流
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        return dis.readUTF(); //读取字符串并返回
    }

    /**
     * 发送Boolean类型数据(客户端与服务器间)
     * @param socket
     * @param flag
     * @throws IOException
     */
    public static void sendBoolean(Socket socket,Boolean flag) throws IOException {
        //只要不是传对象，可使用数据流,将socket中网络流转成数据流
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.writeBoolean(flag);//输出布尔数据
    }

    /**
     * 接收Boolean类型数据(客户端与服务器间)
     * @param socket
     * @throws IOException
     */
    public static boolean receiveBoolean(Socket socket) throws IOException {
        //将socket网络输入流转成数据流
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        return dis.readBoolean();//读取布尔类型
    }

    /**
     * 发送Int类型数据(客户端与服务器间)
     * @param socket
     * @param num
     * @throws IOException
     */
    public static void sendInt(Socket socket,int num) throws IOException {
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.writeInt(num);//输出Int数据
    }

    /**
     * 接收int类型数据(客户端与服务器间)
     * @param socket
     * @return
     * @throws IOException
     */
    public static int receiveInt(Socket socket) throws IOException {
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        return dis.readInt(); //将读取int数据并返回
    }

    /**
     * 接收list集合(c/s之间通信)
     * 数据是对象，使用序列化流，不使用数据流
     * @param socket
     * @return
     */
    public static ArrayList<Express> receiveList(Socket socket) throws IOException, ClassNotFoundException {
        //socket中网络流转成序列化流
        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
        ArrayList<Express> list = (ArrayList<Express>) ois.readObject();//读取数据返回list
        return list;
    }

    /**
     * 发送list类型数据
     * @param socket
     * @param list
     * @return
     */
    public static void sendList(Socket socket,ArrayList<Express>list) throws IOException{
        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        oos.writeObject(list);//发送数据，若C发送则S接收，反之若S发送则C接收
    }
}